/*
 * Dijjer - A Peer to Peer HTTP Cache
 * Copyright (C) 2004,2005 Change.Tv, Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package dijjer.util;

import java.io.IOException;
import java.io.OutputStream;

/**
 * An OutputStream wrapper which ignores the first number of bytes written to the Stream.
 */
public class TruncatingOutputStream extends OutputStream {

	OutputStream _os;
	long _skipBytesToGo, _writtenBytesToGo, _length;

	/**
	 * Wraps an output stream but ignores the first "bytes" bytes written to the stream
	 * 
	 * @param os
	 * @param start
	 */
	public TruncatingOutputStream(OutputStream os, long start) {
		this(os, start, Long.MAX_VALUE);
	}

	public TruncatingOutputStream(OutputStream os, long start, long length) {
		this._os = os;
		this._skipBytesToGo = start;
		this._writtenBytesToGo = length;
		this._length = length;
	}

	public long getLength() {
		return _length;
	}

	public long getBytesTransmitted() {
		return _length - _writtenBytesToGo;
	}

	public void close() throws IOException {
		_os.close();
	}

	public void flush() throws IOException {
		_os.flush();
	}

	public synchronized void write(byte[] arg0, int arg1, int arg2) throws IOException {
		if (_writtenBytesToGo <= 0) {
			return;
		}
		if (_skipBytesToGo <= 0) {
			_os.write(arg0, arg1, (int) Math.min(_writtenBytesToGo, arg2));
			_writtenBytesToGo -= Math.min(_writtenBytesToGo, arg2);
		} else {
			_skipBytesToGo -= arg2;
		}
		if (_skipBytesToGo < 0) {
			_os.write(arg0, (int) (arg1 + arg2 + _skipBytesToGo), (int) (Math.min(_writtenBytesToGo, -_skipBytesToGo)));
			_writtenBytesToGo -= Math.min(_writtenBytesToGo, -_skipBytesToGo);
			_skipBytesToGo = 0;
		}
	}

	public void write(byte[] arg0) throws IOException {
		this.write(arg0, 0, arg0.length);
	}

	public synchronized void write(int arg0) throws IOException {
		if ((_skipBytesToGo <= 0) && (_writtenBytesToGo > 0)) {
			_os.write(arg0);
			_writtenBytesToGo--;
		} else {
			_skipBytesToGo--;
		}
	}
}
